home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Apple WWDC 1996
/
WWDC96_1996 (CD).toast
/
Technology Materials
/
MacOS 8 Resources
/
Developer Tools
/
Mac OS 8 Interfaces & Libraries
/
Interfaces
/
AIncludes
/
MixedMode.a
< prev
next >
Wrap
Text File
|
1996-05-01
|
11KB
|
329 lines
;
; File: MixedMode.a
;
; Contains: Mixed Mode Manager Interfaces.
;
; Version: Technology: System 7.5
; Release: Universal Interfaces 3.0d3 on Copland DR1
;
; Copyright: © 1984-1996 by Apple Computer, Inc. All rights reserved.
;
; Bugs?: If you find a problem with this file, send the file and version
; information (from above) and the problem description to:
;
; Internet: apple.bugs@applelink.apple.com
; AppleLink: APPLE.BUGS
;
;
IF &TYPE('__MIXEDMODE__') = 'UNDEFINED' THEN
__MIXEDMODE__ SET 1
IF &TYPE('__TYPES__') = 'UNDEFINED' THEN
include 'Types.a'
ENDIF
IF FOR_SYSTEM7_AND_SYSTEM8_COOPERATIVE THEN
; Mixed Mode constants
; Current Routine Descriptor Version
kRoutineDescriptorVersion EQU 7
; MixedModeMagic Magic Cookie/Trap number
_MixedModeMagic EQU $AAFE
; Calling Conventions
; typedef unsigned short CallingConventionType
kPascalStackBased EQU 0
kCStackBased EQU 1
kRegisterBased EQU 2
kD0DispatchedPascalStackBased EQU 8
kD1DispatchedPascalStackBased EQU 12
kD0DispatchedCStackBased EQU 9
kStackDispatchedPascalStackBased EQU 14
kThinkCStackBased EQU 5
; ISA Types
; typedef SInt8 ISAType
kM68kISA EQU 0
kPowerPCISA EQU 1
; RTA Types
; typedef SInt8 RTAType
kOld68kRTA EQU $00
kPowerPCRTA EQU $00
kCFM68kRTA EQU $10
; Constants for specifing 68k registers
kRegisterD0 EQU 0
kRegisterD1 EQU 1
kRegisterD2 EQU 2
kRegisterD3 EQU 3
kRegisterD4 EQU 8
kRegisterD5 EQU 9
kRegisterD6 EQU 10
kRegisterD7 EQU 11
kRegisterA0 EQU 4
kRegisterA1 EQU 5
kRegisterA2 EQU 6
kRegisterA3 EQU 7
kRegisterA4 EQU 12
kRegisterA5 EQU 13
kRegisterA6 EQU 14 ; A7 is the same as the PowerPC SP
kCCRegisterCBit EQU 16
kCCRegisterVBit EQU 17
kCCRegisterZBit EQU 18
kCCRegisterNBit EQU 19
kCCRegisterXBit EQU 20
; typedef unsigned short registerSelectorType
; SizeCodes we use everywhere
kNoByteCode EQU 0
kOneByteCode EQU 1
kTwoByteCode EQU 2
kFourByteCode EQU 3
; Mixed Mode Routine Records
; typedef unsigned long ProcInfoType
; Routine Flag Bits
; typedef unsigned short RoutineFlagsType
kProcDescriptorIsAbsolute EQU $00
kProcDescriptorIsRelative EQU $01
kFragmentIsPrepared EQU $00
kFragmentNeedsPreparing EQU $02
kUseCurrentISA EQU $00
kUseNativeISA EQU $04
kPassSelector EQU $00
kDontPassSelector EQU $08
kRoutineIsNotDispatchedDefaultRoutine EQU $00
kRoutineIsDispatchedDefaultRoutine EQU $10
ENDIF
IF FOR_SYSTEM7_AND_SYSTEM8_COOPERATIVE THEN
kProcDescriptorIsProcPtr EQU $00
kProcDescriptorIsIndex EQU $20
RoutineRecord RECORD 0
procInfo ds.l 1 ; offset: $0 (0) ; calling conventions
reserved1 ds.b 1 ; offset: $4 (4) ; Must be 0
ISA ds.b 1 ; offset: $5 (5) ; Instruction Set Architecture
routineFlags ds.w 1 ; offset: $6 (6) ; Flags for each routine
procDescriptor ds.l 1 ; offset: $8 (8) ; Where is the thing we're calling?
reserved2 ds.l 1 ; offset: $C (12) ; Must be 0
selector ds.l 1 ; offset: $10 (16) ; For dispatched routines, the selector
sizeof EQU * ; size: $14 (20)
ENDR
; typedef struct RoutineRecord * RoutineRecordPtr
; typedef RoutineRecordPtr * RoutineRecordHandle
; Mixed Mode Routine Descriptors
; Definitions of the Routine Descriptor Flag Bits
; typedef UInt8 RDFlagsType
kSelectorsAreNotIndexable EQU $00
kSelectorsAreIndexable EQU $01
; Routine Descriptor Structure
RoutineDescriptor RECORD 0
goMixedModeTrap ds.w 1 ; offset: $0 (0) ; Our A-Trap
version ds.b 1 ; offset: $2 (2) ; Current Routine Descriptor version
routineDescriptorFlags ds.b 1 ; offset: $3 (3) ; Routine Descriptor Flags
reserved1 ds.l 1 ; offset: $4 (4) ; Unused, must be zero
reserved2 ds.b 1 ; offset: $8 (8) ; Unused, must be zero
selectorInfo ds.b 1 ; offset: $9 (9) ; If a dispatched routine, calling convention, else 0
routineCount ds.w 1 ; offset: $A (10) ; Number of routines in this RD
routineRecords ds RoutineRecord ; offset: $C (12) <-- really an array of length one ; The individual routines
sizeof EQU * ; size: $20 (32)
ENDR
; typedef struct RoutineDescriptor * RoutineDescriptorPtr
; typedef RoutineDescriptorPtr * RoutineDescriptorHandle
ENDIF
IF FOR_SYSTEM7_AND_SYSTEM8_COOPERATIVE THEN
; Mixed Mode ProcInfos
; Calling Convention Offsets
kCallingConventionWidth EQU 4
kCallingConventionPhase EQU 0
kCallingConventionMask EQU $0F ; Result Offsets
kResultSizeWidth EQU 2
kResultSizePhase EQU 4
kResultSizeMask EQU $30 ; Parameter offsets & widths
kStackParameterWidth EQU 2
kStackParameterPhase EQU 6
kStackParameterMask EQU $FFFFFFC0 ; Register Result Location offsets & widths
kRegisterResultLocationWidth EQU 5
kRegisterResultLocationPhase EQU 6 ; Register Parameter offsets & widths
kRegisterParameterWidth EQU 5
kRegisterParameterPhase EQU 11
kRegisterParameterMask EQU $7FFFF800
kRegisterParameterSizePhase EQU 0
kRegisterParameterSizeWidth EQU 2
kRegisterParameterWhichPhase EQU 2
kRegisterParameterWhichWidth EQU 3 ; Dispatched Stack Routine Selector offsets & widths
kDispatchedSelectorSizeWidth EQU 2
kDispatchedSelectorSizePhase EQU 6 ; Dispatched Stack Routine Parameter offsets
kDispatchedParameterPhase EQU 8 ; Special Case offsets & widths
kSpecialCaseSelectorWidth EQU 6
kSpecialCaseSelectorPhase EQU 4
kSpecialCaseSelectorMask EQU $03F0
ENDIF
IF FOR_SYSTEM7_AND_SYSTEM8_COOPERATIVE THEN
kSpecialCase EQU $000F ; (CallingConventionType)
; all of the special cases enumerated. The selector field is 6 bits wide
kSpecialCaseHighHook EQU 0
kSpecialCaseCaretHook EQU 0 ; same as kSpecialCaseHighHook
kSpecialCaseEOLHook EQU 1
kSpecialCaseWidthHook EQU 2
kSpecialCaseTextWidthHook EQU 2 ; same as kSpecialCaseWidthHook
kSpecialCaseNWidthHook EQU 3
kSpecialCaseDrawHook EQU 4
kSpecialCaseHitTestHook EQU 5
kSpecialCaseTEFindWord EQU 6
kSpecialCaseProtocolHandler EQU 7
kSpecialCaseSocketListener EQU 8
kSpecialCaseTERecalc EQU 9
kSpecialCaseTEDoText EQU 10
kSpecialCaseGNEFilterProc EQU 11
kSpecialCaseMBarHook EQU 12
;
; NOTES ON USING ROUTINE DESCRIPTOR FUNCTIONS
;
; When calling these routine from classic 68k code there are two possible intentions.
;
; The first is source compatibility with code ported to CFM (either PowerPC or 68k CFM). When
; the code is compiled for CFM the functions create routine descriptors that can be used by
; the mixed mode manager operating on that machine. When the code is compiled for classic 68k
; these functions do nothing so that the code will run on Macintoshes that do not have a
; mixed mode manager. The dual nature of these functions is achieved by turning the CFM calls
; into "no-op" macros for classic 68k: You can put "NewRoutineDescriptor" in your source,
; compile it for any runtime or instruction set architecture, and it will run correctly on the
; intended runtime/instruction platform. All without source changes and/or conditional source.
;
; The other intention is for code that "knows" that it is executing as classic 68k runtime
; and is specifically trying to call code of another architecture using mixed mode. Since the
; routines were designed with classic <-> CFM source compatibility in mind this second case
; is treated special. For classic 68k code to create routines descriptors for use by mixed mode
; it must call the "Trap" versions of the routines (NewRoutineDescriptorTrap). These versions
; are only available to classic 68k callers: rigging the interfaces to allow calling them
; from CFM code will result in runtime failure because no shared library implements or exports
; the functions.
;
;
; This almost appears seamless until you consider "fat" routine descriptors and the advent of
; CFM-68K. What does "fat" mean? CFM-68K is not emulated on PowerPC and PowerPC is not emulated
; on CFM-68K. It makes no sense to create a routine descriptor having both a CFM-68K routine
; and a PowerPC native routine pointer. Therefore "fat" is defined to be a mix of classic and
; CFM for the hardware's native instruction set: on PowerPC fat is classic and PowerPC native,
; on a 68k machine with CFM-68K installed fat is classic and CFM-68K.
;
; By definition fat routine descriptors are only constructed by code that is aware of the
; architecture it is executing as and that another architecture exists. Source compatibility
; between code intented as pure classic and pure CFM is not an issue and so NewFatRoutineDescriptor
; is not available when building pure classic code.
;
; NewFatRoutineDescriptorTrap is available to classic code on both PowerPC and CFM-68K. The
; classic code can use the code fragment manager routine "FindSymbol" to obtain the address of
; a routine in a shared library and then construct a routine descriptor with both the CFM routine
; and classic routine.
;
IF GENERATINGCFM THEN
;
; pascal UniversalProcPtr NewRoutineDescriptor(ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
;
IF GENERATINGCFM THEN
IMPORT_CFM_FUNCTION NewRoutineDescriptor
ENDIF
;
; pascal void DisposeRoutineDescriptor(UniversalProcPtr theProcPtr)
;
IF GENERATINGCFM THEN
IMPORT_CFM_FUNCTION DisposeRoutineDescriptor
ENDIF
;
; pascal UniversalProcPtr NewFatRoutineDescriptor(ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
;
IF GENERATINGCFM THEN
IMPORT_CFM_FUNCTION NewFatRoutineDescriptor
ENDIF
ELSE
;
; pascal UniversalProcPtr NewRoutineDescriptorTrap(ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
;
IF ¨ GENERATINGCFM THEN
Macro
_NewRoutineDescriptorTrap
moveq #0,D0
dc.w $AA59
EndM
ELSE
IMPORT_CFM_FUNCTION NewRoutineDescriptorTrap
ENDIF
;
; pascal void DisposeRoutineDescriptorTrap(UniversalProcPtr theProcPtr)
;
IF ¨ GENERATINGCFM THEN
Macro
_DisposeRoutineDescriptorTrap
moveq #1,D0
dc.w $AA59
EndM
ELSE
IMPORT_CFM_FUNCTION DisposeRoutineDescriptorTrap
ENDIF
;
; pascal UniversalProcPtr NewFatRoutineDescriptorTrap(ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
;
IF ¨ GENERATINGCFM THEN
Macro
_NewFatRoutineDescriptorTrap
moveq #2,D0
dc.w $AA59
EndM
ELSE
IMPORT_CFM_FUNCTION NewFatRoutineDescriptorTrap
ENDIF
; Note that the call to NewFatRoutineDescriptor is undefined when GENERATINGCFM is false.
ENDIF
IF GENERATINGCFM THEN
;
; CallUniversalProc is only implemented in shared libraries on 68k and PowerPC, it is now
; conditionalize with GENERATINGCFM. This will catch accidental calls from classic 68K code
; that previously only showed up as linker errors.
;
;
; extern long CallUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...)
;
IF GENERATINGCFM THEN
IMPORT_CFM_FUNCTION CallUniversalProc
ENDIF
;
; extern long CallOSTrapUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...)
;
IF GENERATINGCFM THEN
IMPORT_CFM_FUNCTION CallOSTrapUniversalProc
ENDIF
ENDIF
ENDIF
ENDIF ; __MIXEDMODE__